﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DMSkin;

namespace MySerial
{
    [DefaultEvent("Serial_Received")]
    public partial class Serial_Con : UserControl
    {
        public Serial_Con()
        {
            InitializeComponent();
            //this.sp_Main.NewLine = "\r\n";
        }

        bool _b_Serial_Sta = false;             //串口状态

        private void Serial_Con_Load(object sender, EventArgs e)
        {
            if (cbx_BaudRate.Items.Count > 0)
                cbx_BaudRate.SelectedIndex = 5;   //10  115200
        }

        #region //控件属性
        [Browsable(true), Description("串口状态")]
        /// <summary>
        /// 串口状态
        /// </summary>
        public bool Serial_Sta
        {
            get { return _b_Serial_Sta; }
        }
        [Browsable(true), Description("串口是否打开")]
        /// <summary>
        /// 串口是否打开
        /// </summary>
        public bool IsOpen
        {
            get { return sp_Main.IsOpen; }
        }

        #endregion

        #region 串口事件
        [Browsable(true), Description("串口接收消息事件")]
        /// <summary>
        /// 串口接收消息事件
        /// </summary>
        public event EventHandler Serial_Received;
        [Browsable(true), Description("串口状态改变事件")]
        /// <summary>
        /// 串口状态改变时间
        /// </summary>
        public event EventHandler Serial_StataChange;
        private StringBuilder Builder = new StringBuilder();
        /// <summary>
        /// 串口收到消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void sp_Main_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (sp_Main.IsOpen)
            {
                byte[] Buffer_Get = null;
                //if (Stoping) return;
                try
                {
                    int N = this.sp_Main.BytesToRead;
                    Buffer_Get = new byte[N];
                    this.sp_Main.Read(Buffer_Get, 0, N);
                    Builder.Clear();            //清空
                    Builder.Append(System.Text.Encoding.Default.GetString(Buffer_Get));  //转换为字符串
                    if (Serial_Received != null&&Builder.ToString().Trim()!="")
                    {
                        Serial_Received(Builder, e);
                    }
                }
                finally
                {
                }
            }
        }

        #endregion

        #region 方法
        /// <summary>
        /// 刷新串口
        /// </summary>
        /// <returns>返回可用串口数</returns>
        public int Serial_Refresh()
        {
            cbx_Serial.Items.Clear();
            foreach (Class_Serial.Serial_Info csi in Class_Serial.Serial_Set.GetPorts())
            {
                cbx_Serial.Items.Add(csi.ToString());
            }
            if (cbx_Serial.Items.Count > 0)
                cbx_Serial.SelectedIndex = 0;
            return cbx_Serial.Items.Count;
        }

        /// <summary>
        /// 向串口写数据指令
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        public bool Serial_Write(byte[] buffer, int offset, int count)
        {
            try
            {
                if (sp_Main.IsOpen)
                {
                    sp_Main.Write(buffer, offset, count);
                    return true;
                }
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }

        #endregion

        /// <summary>
        /// 串口开关事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Con_Click(object sender, EventArgs e)
        {
            try
            {
                if (!_b_Serial_Sta)
                {
                    if (cbx_Serial.Text == "" || cbx_BaudRate.Text == "")
                    {
                        //MessageBox.Show("请选择对应串口和波特率后继续！", "提示");
                        DMSkin.MetroMessageBox.Show(this.ParentForm, "请选择对应串口和波特率后继续！", "提示");
                        return;
                    }
                    sp_Main.PortName = cbx_Serial.Text.Split('-')[0];
                    sp_Main.BaudRate = int.Parse(cbx_BaudRate.Text);
                    sp_Main.Open();
                    btn_Con.Text = "断开";
                    cbx_Serial.Enabled = false;
                    cbx_BaudRate.Enabled = false;
                    pic_Stat.Enabled = false;
                    pic_Stat.Image = Properties.Resources.open;
                    _b_Serial_Sta = true;
                    
                }
                else
                {
                    if (sp_Main.IsOpen)
                    {
                        sp_Main.Close();
                    }
                    btn_Con.Text = "连接";
                    cbx_Serial.Enabled = true;
                    cbx_BaudRate.Enabled = true;
                    pic_Stat.Enabled = true;
                    pic_Stat.Image = Properties.Resources.lost;
                    _b_Serial_Sta = false;
                }
                if (Serial_StataChange != null)
                    Serial_StataChange(_b_Serial_Sta, null);
            }
            catch
            {
                pic_Stat.Image = Properties.Resources.lost1;
                //MessageBox.Show("请检查串口号是否正确或串口是否被占用！", "打开失败");
                DMSkin.MetroMessageBox.Show(this.ParentForm, "请检查串口号是否正确或串口是否被占用！", "打开失败");
            }
        }


        /// <summary>
        /// 鼠标单击刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pic_Stat_Click(object sender, EventArgs e)
        {
            Serial_Refresh();
        }

        private void cbx_Serial_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
